package com.starmark.gateway.auth.provider.service.impl;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.starmark.core.framework.base.AbstractBaseService;
import com.starmark.core.framework.util.RedisUtils;
import com.starmark.gateway.auth.provider.entity.GatewayAuthRole;
import com.starmark.gateway.auth.provider.entity.GatewayAuthRor;
import com.starmark.gateway.auth.provider.entity.GatewayAuthRrr;
import com.starmark.gateway.auth.provider.mapper.GatewayAuthRoleMapper;
import com.starmark.gateway.auth.provider.mapper.GatewayAuthRorMapper;
import com.starmark.gateway.auth.provider.mapper.GatewayAuthRrrMapper;
import com.starmark.gateway.auth.provider.service.IGatewayAuthResourceService;
import com.starmark.gateway.auth.provider.service.IGatewayAuthRoleService;
import com.starmark.gateway.auth.provider.vo.AuthOrgElementDto;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author starmark
 * @since 2018-04-27
 */
@Service("gatewayAuthRoleService")
public class GatewayAuthRoleServiceImpl extends AbstractBaseService<GatewayAuthRoleMapper, GatewayAuthRole> implements IGatewayAuthRoleService {

    private static final String STARMARK_GATEWAY_RRR = "starmark:gateway:rrr:";

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    GatewayAuthRrrMapper gatewayAuthRrrMapper;


    @Autowired
    GatewayAuthRorMapper gatewayAuthRorMapper;


    @Autowired
    IGatewayAuthResourceService authResourceService;


    @Override
    public Set<String> getRoleIdsByOrgId(List<String> orgIds, String projectCode) {
        return this.getBaseMapper().getRoleIdsByOrgId(orgIds, projectCode);
    }


    @Override
    public boolean isAdmin(String orgId, String projectCode) {
        return this.getBaseMapper().isAdmin(orgId, projectCode);
    }

    @Override
    public void buildPageSearch(Map<String, Object> params, QueryWrapper<GatewayAuthRole> eWrapper) {
        if (params.get("keyword") != null && StrUtil.isNotEmpty(params.get("keyword") + "")) {
            eWrapper.like("name", params.get("keyword") + "").or().like("code", params.get("keyword") + "");

        }
        //查询工程ID
        eWrapper.eq("project_code", params.get("projectCode") + "");
        //只查非超级管理员的数据
        eWrapper.eq("admin", false);
    }

    @Override
    public List<String> getRoleResource(String roleId) {
        return gatewayAuthRrrMapper.getRoleResource(roleId);
    }


    @Override
    public List<AuthOrgElementDto> getRoleOrg(String roleId) {

        return gatewayAuthRorMapper.getRoleOrg(roleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grantAuthToRole(String roleId, List<String> entityIds) {
        Assert.hasText(roleId, "角色ID不存在");
        GatewayAuthRole authRole = this.getById(roleId);
        Assert.notNull(authRole, "角色不存在:" + roleId);
        if (CollectionUtils.isEmpty(entityIds)) {
            //如果传入的菜单为空，则直接清空授权
            gatewayAuthRrrMapper.deleteByRoleId(roleId);
            return;
        }

        List<String> existResourceId = gatewayAuthRrrMapper.getRoleResource(roleId);

        List<String> existIds = new ArrayList<>();
        if (existResourceId != null) {
            for (String resourceId : existResourceId) {
                if (!entityIds.contains(resourceId)) {
                    //旧的授权不在传入的数组内则删除
                    gatewayAuthRrrMapper.deleteByRoleIdAndResourceId(roleId, resourceId);
                } else {
                    existIds.add(resourceId);
                }
            }
        }

        entityIds.forEach(id -> {
            if (!existIds.contains(id)) {
                //插入新的数据
                GatewayAuthRrr authRrr = new GatewayAuthRrr();
                authRrr.setResId(id);
                authRrr.setRoleId(roleId);
                gatewayAuthRrrMapper.insert(authRrr);
            }
        });
        redisUtils.set(STARMARK_GATEWAY_RRR + authRole.getProjectCode() + ":" + roleId, JSONArray.toJSONString(entityIds));
    }




    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grantAuthOrgRole(String roleId, List<AuthOrgElementDto> orgElementDtos) {

        if (orgElementDtos == null || orgElementDtos.isEmpty()) {
            //如果传入的菜单为空，则直接清空授权
            gatewayAuthRorMapper.deleteByRoleId(roleId);
            return;
        }


        List<AuthOrgElementDto> existResources = gatewayAuthRorMapper.getRoleOrg(roleId);

        List<AuthOrgElementDto> existIds = new ArrayList<>();
        if (existResources != null) {
            for (AuthOrgElementDto orgElementDto : existResources) {
                if (!orgElementDtos.contains(orgElementDto)) {
                    //旧的授权不在传入的数组内则删除
                    gatewayAuthRorMapper.deleteByRoleIdAndOrgId(roleId, orgElementDto.getId());
                } else {
                    existIds.add(orgElementDto);
                }
            }
        }

        orgElementDtos.forEach(orgElementDto -> {
            if (!existIds.contains(orgElementDto)) {
                //插入新的数据
                GatewayAuthRor authRor = new GatewayAuthRor();
                authRor.setOrgId(orgElementDto.getId());
                authRor.setRoleId(roleId);
                authRor.setOrgName(orgElementDto.getName());
                authRor.setOrgType(orgElementDto.getOrgType());
                gatewayAuthRorMapper.insert(authRor);
            }
        });

    }



    @Override
    public boolean overload() {
        List<GatewayAuthRole> roles = this.list();
        roles.forEach(role -> {
            List<String> entityIds = this.getRoleResource(role.getId());
            redisUtils.set(STARMARK_GATEWAY_RRR + role.getProjectCode() + ":" + role.getId(), JSONArray.toJSONString(entityIds));

        });

        return true;
    }




}
